package com.dsteiner.widgets.client;

import java.util.Date;

import com.dsteiner.widgets.client.constants.Constants;
import com.google.gwt.core.client.Duration;
import com.google.gwt.i18n.client.DateTimeFormat;

public class DateUtilImpl implements IDateUtil{

	private static DateUtilImpl instance;
	
	private DateUtilImpl() {
	}
	
	public static IDateUtil getInstance(){
		if(instance == null)
			instance = new DateUtilImpl();
		return instance;	
	}
	
	public static final long DAY_IN_MS = 86400000;
	
	public static final long MIN_IN_MS = 60000;
	
	static DateTimeFormat formatter = DateTimeFormat.getFormat("MMM d, yy");
	
	static DateTimeFormat formatterLong = DateTimeFormat.getFormat("EEE, MMM-dd (h:mma)");
	
	static DateTimeFormat formatterShort = DateTimeFormat.getFormat("MM/dd/yy");
	
	static DateTimeFormat formatterSummary = DateTimeFormat.getFormat("yyyy-MM-dd");
	
	public static DateTimeFormat formatterSpanish = DateTimeFormat.getFormat(Constants.SPANISH_DATE_FORMAT);
	
	public static DateTimeFormat formatterSpanishLong = DateTimeFormat.getFormat(Constants.SPANISH_DATE_FORMAT_LONG);
	
	public static DateTimeFormat formatterHour = DateTimeFormat.getFormat("HH:mm");
	
	static DateTimeFormat formatterPhp = DateTimeFormat.getFormat("yyyy/MM/dd");
	
	static DateTimeFormat dbDateParser = DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss");
	
	static DateTimeFormat aggregatesDateParser = DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss-ss");
	static DateTimeFormat stringDateParser = DateTimeFormat.getFormat("EEE MMM dd HH:mm:ss 'CST' yyyy");

	static DateTimeFormat sdfMonth = DateTimeFormat.getFormat("MMM d yyyy");
	
	static DateTimeFormat sdfLong = DateTimeFormat.getFormat("yyyy-MM-dd hh:mm:ss");

	static DateTimeFormat[] dateTimeParser = new DateTimeFormat[]{dbDateParser, sdfMonth, sdfLong, aggregatesDateParser,
		formatterShort, formatterSpanish, formatterHour};
	

    public static String formatDatePassedSince(Date date) {
    	long timeNow = new Date().getTime();
    	long time = date.getTime();
    	long timeDiff = timeNow - time;
    	
    	long timeInMinsDiff = timeDiff / MIN_IN_MS;
    	if(timeInMinsDiff == 0){
    		return "hace un rato";
    	}
    	else if(timeInMinsDiff < 60){
    		return "hace "+timeInMinsDiff+(timeInMinsDiff == 1 ? " minuto" : " minutos");
    	}
    	else if(timeInMinsDiff < 24 * 60){
    		long hours = timeInMinsDiff / 60;
			return "hace "+hours+(hours == 1 ? " hora" : " horas");
    	}
    	else if(timeInMinsDiff < 30 * 24 * 60){
    		long days = timeInMinsDiff / (60*24);
			return "hace "+days+(days == 1 ? " dia" : " dias");
    	}
    	else{
    		long months = timeInMinsDiff / (30*60*24);
    		return "hace "+months+(months== 1 ? " mes" : " meses");
    	}
    		
    }
    
    public static String formatDate(Date date) {
		return formatter.format(date);
	}
	
	public static String formatDateLong(Date date) {
		return formatDate(formatterLong, date);
	}
	public String formatDateSpanish(Date date) {
		return formatDate(formatterSpanish, date);
	}
	
	public static String formatDate(DateTimeFormat formatter, Date date) {
		if(date == null)
			return null;
		return formatter.format(date);
	}

	public static String formatDateSummary(Date date) {
		return formatterSummary.format(date);
	}

	public static String formatDateShort(Date date){
		if(date == null)
			return null;
		return formatterShort.format(date);
	}

	public static Date parseDate(String dateObj, DateTimeFormat dateTimeFormat) {
		try{
			String trim = dateObj.trim();
			Date date = dateTimeFormat.parse(trim);
			return date;
		}catch(Exception ex){
		}
		return null;
	}
	
	public static String getDaysFromNowInMsAsString(int days) {
		Date resultDate = getDaysFromNow(days);
		return formatterPhp.format(resultDate);
	}

	public static Date getDaysFromNow(int days) {
		double msNow = new Date().getTime();
		double daysInMs = (days * DAY_IN_MS);
		double time = msNow + daysInMs;
		Date resultDate = new Date((long)time);
		return resultDate;
	}

	public static String formatHour(Date eventHour) {
		return formatterHour.format(eventHour);
	}

	public int getAge(Date birthday) {
		long time = new Date().getTime() - birthday.getTime();
		return (int) (time / DAY_IN_MS / 365);
	}

	public boolean isDateSpanish(String date) {
		return parseDateSpanish(date) != null;
	}
	
	public Date parseDateSpanish(String date) {
		return parseDate(date, DateUtilImpl.formatterSpanish);
	}


}
